package org.apple.databanker;

import java.util.ArrayList;
import java.util.Random;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;

import org.apple.data.SensorReading;
import org.apple.util.Configure;

public class RAMDataBanker implements DataBanker {
	
	private static ArrayList<SensorReading> wsList = new ArrayList<SensorReading>();//for wind speed
	
	private static ArrayList<SensorReading> atList = new ArrayList<SensorReading>();//for air temperature 

	private static ArrayList<SensorReading> stList = new ArrayList<SensorReading>();//for sea temperature
	
	private static int WS_HL; // wind speed history length
	
	private static int AT_HL; // air temperature history length
	
	private static int ST_HL; // sea temperature history length
	
	public RAMDataBanker(){
		Configure conf = Configure.instance();
		String wshl = conf.getProperty("windSpeedHistory");
		String athl = conf.getProperty("airTemperatureHistory");
		String sthl = conf.getProperty("seaTemperatureHistory");
		WS_HL = Integer.valueOf(wshl==null?"0":wshl);
		AT_HL = Integer.valueOf(athl==null?"0":athl);
		ST_HL = Integer.valueOf(sthl==null?"0":sthl);
	}
	
	/**
	 * write a new SensorReading into databanker
	 */
	public void write(SensorReading sensorReading, int sensorType) {
		switch(sensorType){
		case SensorReading.SPEED:
			update(wsList, WS_HL, sensorReading);
			break;
		case SensorReading.AIRTEMPRATURE:
			update(atList, AT_HL, sensorReading);
			break;
		case SensorReading.SEATEMPRATURE:
			update(stList, ST_HL, sensorReading);
			break;
		default:
			throw new RuntimeException("SensorType is invalid");
		}
	}
	
	private synchronized static void update(ArrayList<SensorReading> list, int length, SensorReading data){
		if(length>0){
			if(list.size()>=length){
				list.remove(0);
				list.add(data);
			}else{
				list.add(data);
			}
		}
		
	}
	
	/**
	 * read data from data banker
	 */
	public void read(Vector<SensorReading> collector, int sensorType) {
		switch(sensorType){
		case SensorReading.SPEED:
			this.copy(wsList, collector);
			break;
		case SensorReading.AIRTEMPRATURE:
			this.copy(atList, collector);
			break;
		case SensorReading.SEATEMPRATURE:
			this.copy(stList, collector);
			break;
		default:
			throw new RuntimeException("SensorType is invalid");
		}
	}
	/**
	 * copy list to the result
	 * @param list
	 * @param result
	 */
	private void copy(ArrayList<SensorReading> list, Vector<SensorReading> result){
		result.clear();
		for (SensorReading r : list) {
			SensorReading  sr = new SensorReading(r.getSensorType(),r.getResolutionType(),r.getValue());
			result.add(sr);
		}
	}
	
	public static void main(String[] args){
		RAMDataBanker db = new RAMDataBanker();
		
		//write data
		for(int i = 0;i<20;i++){
			int type = new Random().nextInt(3)+1;
			int rt = new Random().nextInt(2);
			double value = new Random().nextDouble()*100;
			System.out.println("putting:"+type+"\t"+rt+"\t"+value);
			SensorReading sr = new SensorReading(type,rt,value);
			db.write(sr, type);
		}
		//end write
		
		Vector<SensorReading> v = new Vector<SensorReading>();
		db.read(v, SensorReading.SPEED);
		System.out.println("reading ws----------------");
		for (SensorReading sr : v) {
			System.out.println(sr.getSensorType()+"\t"+sr.getResolutionType()+"\t"+sr.getValue());
		}
		
		db.read(v, SensorReading.AIRTEMPRATURE);
		System.out.println("reading at----------------");
		for (SensorReading sr : v) {
			System.out.println(sr.getSensorType()+"\t"+sr.getResolutionType()+"\t"+sr.getValue());
		}
		
		db.read(v, SensorReading.SEATEMPRATURE);
		System.out.println("reading st----------------");
		for (SensorReading sr : v) {
			System.out.println(sr.getSensorType()+"\t"+sr.getResolutionType()+"\t"+sr.getValue());
		}
	}
}
